package com.tfswx.jkgl.core.interfaces.delete.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.tfswx.jkgl.core.bean.JkglRuntimeData;
import com.tfswx.jkgl.core.bean.SjmxXtMxdy;
import com.tfswx.jkgl.core.bean.TSjmxXtMxstgx;
import com.tfswx.jkgl.core.dto.CsdygxInputDTO;
import com.tfswx.jkgl.core.dto.DeleteInputDTO;
import com.tfswx.jkgl.core.interfaces.delete.AbstractDeleteHandleComponent;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.jdbc.SQL;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author zhanglj
 * @description: sql处理类型
 * @date 2021/12/8 9:30
 **/
@Component
public class SjmxDeleteHandleComponent extends AbstractDeleteHandleComponent {

    @Resource
    private JkglRuntimeData jkglRuntimeData;

    /**
     * 获取处理程序名称
     *
     * @return
     */
    @Override
    public String getClcx() {
        return "sjmx";
    }

    /**
     * 依据删除请求参数生成指定删除sql语句
     *
     * @param dto
     * @return
     */
    @Override
    public List<String> createSql(final DeleteInputDTO dto) throws Exception {
        final List<String> deleteSqlList = new LinkedList<>();

        // 1、判断请求参数中是否有数据模型编码
        if (StringUtils.isEmpty(dto.getClcx().getClcxcs())) {
            throw new Exception("传入参数数据模型编码为空");
        }

        // 2、判断需要删除数据项的表信息是否为空
        if (StringUtils.isEmpty(dto.getClcx().getClcxcs())) {
            throw new Exception("传入需要删除数据的表信息不能为空");
        }

        // 3、依据模型编码获取模型定义信息
        SjmxXtMxdy mx = this.getMx(dto.getClcx().getClcxcs());
        if (Objects.isNull(mx)) {
            throw new Exception("传入参数数据模型编码错误：" + dto.getClcx().getClcxcs());
        }

        List<String> tables = new LinkedList<>();
        tables.add(mx.getZSTMC());

        // 4、依据模型编码获模型实体表关系信息
        List<TSjmxXtMxstgx> allMxstgx = this.getAllMxstgx(dto.getClcx().getClcxcs());
        if (Objects.nonNull(allMxstgx) && !allMxstgx.isEmpty()) {
            // 判断传入参数中需要进行数据项删除的表是否是该数据模型关联表，如果不是，则跳过构建逻辑删除操作SQL语句。
            List<String> zstmcs = allMxstgx.stream().filter(item -> "N".equalsIgnoreCase(item.getSFSC()))
                    .map(TSjmxXtMxstgx::getZSTMC).filter(item -> StringUtils.isNotEmpty(item))
                    .distinct()
                    .collect(Collectors.toList());
            tables.addAll(zstmcs);

            List<String> cstmc = allMxstgx.stream().filter(item -> "N".equalsIgnoreCase(item.getSFSC()))
                    .map(TSjmxXtMxstgx::getCSTMC).filter(item -> StringUtils.isNotEmpty(item))
                    .distinct()
                    .collect(Collectors.toList());
            tables.addAll(cstmc);
        }

        tables = tables.stream().distinct().collect(Collectors.toList());

        List<Map<String, Object>> array = new ArrayList<>();

        if (dto.getCsdy() instanceof Map) {
            array.add((Map<String, Object>) dto.getCsdy());
        } else {
            array.addAll((Collection<? extends Map<String, Object>>) dto.getCsdy());
        }

        for (int i = 0; i < array.size(); i++) {
            Map<String, Object> jsonObject = array.get(i);
            // 5、遍历需要删除(逻辑删除)数据的表信息以及表关联信息，封装删除语句
            for (final String deleteTable : dto.getScbjh()) {

                if (!tables.contains(deleteTable)) {
                    continue;
                }

                SQL deleteSql = new SQL();
                deleteSql.UPDATE(deleteTable);
                deleteSql.SET("SFSC  = 'Y'");
                // 遍历分组后的表数据，生成指定表的删除语句
                Iterator<CsdygxInputDTO> iterator = dto.getCsgx().iterator();
                while (iterator.hasNext()) {
                    CsdygxInputDTO next = iterator.next();
                    if (next.getStmc().equals(deleteTable)) {
                        //字段名称为空则跳过
                        if(ObjectUtil.isNull(next.getZdmc())){
                            continue;
                        }
                        String value = String.valueOf(jsonObject.get(next.getCsbm()));
                        if (!StringUtils.isEmpty(value)) {
                            deleteSql.WHERE(next.getZdmc() + " = '" + value + "'");
                        }
                    }
                }

                if (!deleteSql.toString().contains("where") && !deleteSql.toString().contains("WHERE")) {
                    throw new Exception("需要删除的表" + deleteTable + "没有删除条件");
                }

                deleteSqlList.add(deleteSql.toString());
            }
        }

        return deleteSqlList;
    }

    /**
     * 获取JSONObject中指定参数数据值
     *
     * @param object
     * @param csbm
     * @return
     */
    private String getParamValue(JSONObject object, String csbm) {
        Iterator<String> iterator = object.keySet().iterator();
        while (iterator.hasNext()) {
            String next = iterator.next();
            if (csbm.equals(next)) {
                return object.getString(csbm);
            }
        }
        return null;
    }

    /**
     * 依据模型编码获取数据模型实体表关联关系
     *
     * @param mxbm
     * @return
     */
    private List<TSjmxXtMxstgx> getAllMxstgx(String mxbm) {
        return this.jkglRuntimeData.getMxstgxList().get(mxbm);
    }

    /**
     * 依据模型编码获取数据模型定义关系
     *
     * @param mxbm
     * @return
     */
    private SjmxXtMxdy getMx(String mxbm) {
        return this.jkglRuntimeData.getMxdyList().get(mxbm);
    }
}
